﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

using Auto.IService.IServices;
using Auto.Model;
using Auto.Model.Dto;
using Auto.Model.Entities;
using Auto.Tools.Standards;
using Auto.Tools.Standards.Extends;
using Auto.Tools.Standards.ServiceResult;
using Auto.Web.ExceptionHandling;
using Auto.Web.Helpers;
using Auto.Web.IDSConfigs.Constants;
using Auto.Web.Models;

using AutoMapper;

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using static Auto.Tools.Standards.EnumCollection;

namespace Auto.Web.Controllers
{

    //[Authorize(Policy = AuthorizationConsts.AdministrationPolicy)]
    //[TypeFilter(typeof(ControllerExceptionFilterAttribute))]
    public class CorporationController : BaseController
    {
        public CorporationController(IMapper mapper, ICorporationService corporationService, IAreaService areaService, ILogger<CorporationController> logger)
        {
            AutoMapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
            CorporationService = corporationService ?? throw new ArgumentNullException(nameof(corporationService));
            AreaService = areaService ?? throw new ArgumentNullException(nameof(areaService));
            Logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }
        /// <summary>
        /// 映射组件
        /// </summary>
        public IMapper AutoMapper { get; }
        /// <summary>
        /// Corporation 服务
        /// </summary>
        public ICorporationService CorporationService { get; }
        /// <summary>
        /// Area服务
        /// </summary>
        public IAreaService AreaService { get; }
        /// <summary>
        /// 日志
        /// </summary>
        public ILogger Logger { get; }
        /// <summary>
        /// 创建公司新页面
        /// </summary>
        /// <returns></returns>
        public IActionResult Creation()
        {
            return View();
        }
        /// <summary>
        /// 创建公司数据提交
        /// </summary>
        /// <param name="creationUpdateDto">提交公司信息</param>
        /// <returns></returns>
        [HttpPost, ValidateAntiForgeryToken]
        public async Task<IActionResult> Creation([FromForm] CorporationCreationUpdateDto creationUpdateDto)
        {
            ServiceSingleDataResult<CorporationDto> Result = new ServiceSingleDataResult<CorporationDto>();
            var ResultMsg = string.Empty;
            if (!ModelState.IsValid)
            {
                //ModelState.AddModelError(string.Empty, "自定义描述错误");
                //ModelState.Remove("AreaID");
                //ViewBag.ModelState = ModelState;
                //ViewData["ModelState"] = ModelState;
                //var values = ModelState.Values.Where(s => s.Errors.Any());
                ViewBag.AreaIDs = string.Join(",", creationUpdateDto.AreaID);
                Dictionary<string, string> ModelErrors = new Dictionary<string, string>();

                var keys = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0);
                foreach (var key in keys)
                {
                    if (key == "AreaID")
                    {
                        ResultMsg = "请正确选择区划地址！";
                    }
                    else
                    {
                        foreach (var error in ModelState[key].Errors)
                        {
                            ResultMsg += ' ' + error.ErrorMessage;
                        }
                    }
                    ModelErrors.Add(key, ResultMsg);
                }

                Result.JsonData = new { ModelErrors, AreaIDs = string.Join(",", creationUpdateDto.AreaID) };
                ResultMsg = Constants.ResultMessage.ModelStateInValidMessage;
                Result.IsFailedOrException(ResultMsg, resultCode: ResultCode.ModelStateInValid);

                return Json(Result);
            }

            var firstArerID = creationUpdateDto.AreaID.FirstOrDefault();
            if (Constants.SpecialAdministrativeRegionAreaID.Contains(firstArerID))
            {
                if (creationUpdateDto.AreaID.Count < 2)
                {
                    ResultMsg = Constants.ResultMessage.ArgumentsLostMessage + "请选择完整的区划地址";
                    Result.IsFailedOrException(ResultMsg, resultCode: ResultCode.ArgumentsLost);
                    return Json(Result);
                }
            }
            if (creationUpdateDto.AreaID.Count < 4)
            {
                ResultMsg = "请选择完整的区划地址";
                Result.IsFailedOrException(ResultMsg, resultCode: ResultCode.ArgumentsLost);
                return Json(Result);
            }

            Corporation corporation = AutoMapper.Map<Corporation>(creationUpdateDto);
            if (corporation.ID <= 0)
            {
                corporation.CreatorUserID = 1000;
                corporation.CreationTime = DateTime.Now.ToLocalTime();
                if (CorporationService.IsExisted(corporation))
                {
                    ResultMsg = Constants.ResultMessage.FailedMessage + "分公司信息已存在！";
                    Result.IsFailedOrException(ResultMsg);
                    return Json(Result);
                }
                CorporationService.Create(corporation);
                var result = await CorporationService.SaveChangeAsync();
                if (result > 0)
                {
                    Result.IsSuccesful(Constants.ResultMessage.SuccessfulMessage);
                    return Json(Result);
                }
                ResultMsg = Constants.ResultMessage.FailedMessage;
                Result.IsSuccesful(ResultMsg);
                return Json(Result);

            }

            return Json(Result);
        }

        /// <summary>
        /// 修改公司页面
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public async Task<IActionResult> Edit([FromQuery] int? ID)
        {
            var ResultMsg = string.Empty;
            ServiceSingleDataResult<CorporationDto> Result = new ServiceSingleDataResult<CorporationDto>();
            if (ID == null)
            {
                ResultMsg = Constants.ResultMessage.ArgumentsLostMessage;
                Logger.LogError(ResultMsg + "未接收到ID");
                Result.IsFailedOrException(ResultMsg, Request.Headers["Referer"].ToString());
                ViewBag.Result = Result;
                return View(Result.Data);
            }

            Expression<Func<Corporation, bool>> wherelambda = c => c.IsActive == true && c.IsDeleted == false;
            wherelambda = wherelambda.And(c => c.ID == ID);

            Corporation corporation = await CorporationService.GetEntityAsync(wherelambda);

            if (corporation == null)
            {
                ResultMsg = Constants.ResultMessage.NotFoundMessage; ;
                Logger.LogWarning(ResultMsg);
                Result.IsFailedOrException(ResultMsg, Request.Headers["Referer"].ToString());
                ViewBag.Result = Result;
                return View(Result.Data);
            }
            Result.Data = AutoMapper.Map<CorporationDto>(corporation);
            int AreaID = corporation.AreaID;
            Expression<Func<Area, bool>> wherelambdaArea = c => c.ID == AreaID;
            wherelambdaArea = wherelambdaArea.And(c => c.IsActive == true && c.IsDeleted == false);
            var area = await AreaService.GetEntityAsync(wherelambdaArea);
            Result.Data.AreaAddress = area == null ? "区划地址数据丢失" : area.MergerName.Replace(',', ' ');
            var AreaIDs = AreaService.GetAllAreaParentID(AreaID);
            Result.Data.AreaIDs = string.Join(',', AreaIDs);
            Result.IsSuccesful();
            //测试组件
            //ErrorMsg = "展示数据已丢失或不存在，请核实！";
            //Logger.LogWarning(ErrorMsg);
            // Result.IsFailedOrError(ErrorMsg, Request.Headers["Referer"].ToString());
            ViewBag.Result = Result;
            return View(Result.Data);
        }
        /// <summary>
        /// 修改公司数据提交
        /// </summary>
        /// <param name="creationUpdateDto">提交公司信息</param>
        /// <returns></returns>
        [HttpPost, ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit([FromForm] CorporationCreationUpdateDto creationUpdateDto)
        {
            ServiceSingleDataResult<CorporationDto> Result = new ServiceSingleDataResult<CorporationDto>();
            var ResultMsg = string.Empty;
            #region 判断：接收参数是否有误
            if (!ModelState.IsValid)
            {
                ViewBag.AreaIDs = string.Join(",", creationUpdateDto.AreaID);
                Dictionary<string, string> ModelErrors = new Dictionary<string, string>();

                var keys = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0);
                foreach (var key in keys)
                {
                    if (key == "AreaID")
                    {
                        ResultMsg = "请正确选择区划地址！";
                    }
                    else
                    {
                        foreach (var error in ModelState[key].Errors)
                        {
                            ResultMsg += ' ' + error.ErrorMessage;
                        }
                    }
                    ModelErrors.Add(key, ResultMsg);
                }
                Result.JsonData = new { ModelErrors, AreaIDs = string.Join(",", creationUpdateDto.AreaID) };
                ResultMsg = Constants.ResultMessage.ModelStateInValidMessage + "数据校验非法，请核实！";
                Result.IsFailedOrException(ResultMsg, resultCode: ResultCode.ModelStateInValid);
                return Ok(Result);
            }
            if (creationUpdateDto.ID < 1)
            {
                ResultMsg = Constants.ResultMessage.ArgumentsLostMessage + "主键ID数据！";
                Result.IsFailedOrException(ResultMsg, resultCode: ResultCode.ArgumentsLost);
                Logger.LogWarning(ResultMsg);
                return Ok(Result);
            }
            #endregion

            #region 判断：修改对象是否正常
            Expression<Func<Corporation, bool>> wherelambda = c => c.IsActive == true && c.IsDeleted == false;
            wherelambda = wherelambda.And(c => c.ID == creationUpdateDto.ID);
            Corporation corporationEditing = await CorporationService.GetEntityAsync(wherelambda, true);
            if (corporationEditing == null)
            {
                ResultMsg = Constants.ResultMessage.FailedMessage + "数据丢失或已删除，请核实！";
                Result.IsFailedOrException(ResultMsg);
                Logger.LogWarning(ResultMsg);
                return Json(Result);
            }
            //await CorporationService.context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
            #endregion

            #region 判断：是否填选择了区划地址
            var ArerID = creationUpdateDto.AreaID.FirstOrDefault();
            if (Constants.SpecialAdministrativeRegionAreaID.Contains(ArerID))
            {
                if (creationUpdateDto.AreaID.Count < 2)
                {
                    ResultMsg = Constants.ResultMessage.ArgumentsLostMessage + "请选择完整的区划地址";
                    Result.IsFailedOrException(ResultMsg, resultCode: ResultCode.ArgumentsLost);
                    return Json(Result);
                }
            }
            if (creationUpdateDto.AreaID.Count < 4)
            {
                ResultMsg = Constants.ResultMessage.ArgumentsLostMessage + "请选择完整的区划地址";
                Result.IsFailedOrException(ResultMsg, resultCode: ResultCode.ArgumentsLost);
                return Json(Result);
            }

            #endregion

            corporationEditing = AutoMapper.Map<Corporation>(creationUpdateDto);
            #region 判断：修改后数据是否已存在
            var IsExisted = CorporationService.IsExisted(corporationEditing);
            if (IsExisted)
            {
                ResultMsg = Constants.ResultMessage.FailedMessage + "分公司数据已存在，请核实！";
                Result.IsFailedOrException(ResultMsg);
                Logger.LogWarning(ResultMsg);
                return Json(Result);
            }
            #endregion
            corporationEditing.ModificationUserID = 1001;
            corporationEditing.LastModificationTime = DateTime.Now.ToLocalTime();
            CorporationService.Update(corporationEditing);
            var result = await CorporationService.SaveChangeAsync();
            if (result > 0)
            {
                ResultMsg = Constants.ResultMessage.SuccessfulMessage;
                Result.IsSuccesful(ResultMsg);
                Logger.LogInformation(ResultMsg);
                return Json(Result);
            }
            ResultMsg = Constants.ResultMessage.FailedMessage + "待修改数据，提交失败！";
            Logger.LogWarning($"{ ResultMsg }分公司ID= {corporationEditing.ID},分公司名称={corporationEditing.Name}");

            Result.IsFailedOrException(ResultMsg);
            return Json(Result);
        }

        /// <summary>
        /// 公司列表
        /// </summary>
        /// <returns></returns>
        public IActionResult List()
        {
            return View();
        }
        /// <summary>
        /// 公司列表数据获取
        /// </summary>
        /// <param name="FromData"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ListPageDataLoading([FromBody] JObject FromData)
        {
            CorporationSearchParamsDto Argus = FromData.JsonToClass<CorporationSearchParamsDto>();

            ServicePageDataResult<CorporationDto> pageData = new ServicePageDataResult<CorporationDto>();
            //查询条件
            Expression<Func<CorporationDto, bool>> wherelambda = c => true;
            wherelambda = wherelambda.And(c => c.IsDeleted == false);
            //排序字段（单字段）
            Expression<Func<CorporationDto, object>> orderLambda = c => c.ID;

            pageData.PageIndex = Argus.PageNumber;
            pageData.PageSize = Argus.PageSize;

            pageData = CorporationService.LoadPageDataList(wherelambda, orderLambda, pageData.PageIndex, pageData.PageSize, true);
            return Json(pageData);
        }

        /// <summary>
        /// 公司详情信息展示页面
        /// </summary>
        /// <param name="ID">公司主键ID</param>
        /// <returns></returns>
        public async Task<IActionResult> Details([FromQuery] int? ID)
        {
            ServiceSingleDataResult<CorporationDto> Result = new ServiceSingleDataResult<CorporationDto>();
            var ResultMsg = string.Empty;
            if (ID == null)
            {
                ResultMsg = "详情展示数据已丢失或不存在，请核实！";
                Logger.LogWarning(ResultMsg + "异常信息：未接收到ID");
                Result.IsFailedOrException(ResultMsg, Request.Headers["Referer"].ToString());
                return View(Result);
            }

            Expression<Func<Corporation, bool>> wherelambda = c => c.IsActive == true && c.IsDeleted == false;
            wherelambda = wherelambda.And(c => c.ID == ID);

            Corporation corporation = await CorporationService.GetEntityAsync(wherelambda);

            if (corporation == null)
            {
                ResultMsg = "展示数据已丢失或不存在，请核实！";
                Logger.LogWarning(ResultMsg);
                Result.IsFailedOrException(ResultMsg, Request.Headers["Referer"].ToString());
                return View(Result);
            }
            Result.Data = AutoMapper.Map<CorporationDto>(corporation);
            int AreaID = corporation.AreaID;
            Expression<Func<Area, bool>> wherelambdaArea = c => c.ID == AreaID;
            wherelambdaArea = wherelambdaArea.And(c => c.IsActive == true && c.IsDeleted == false);
            var area = await AreaService.GetEntityAsync(wherelambdaArea);
            Result.Data.AreaAddress = area == null ? "区划地址数据丢失" : area.MergerName.Replace(',', ' ');
            var AreaIDs = AreaService.GetAllAreaParentID(AreaID);
            Result.Data.AreaIDs = string.Join(',', AreaIDs);
            ResultMsg = Constants.ResultMessage.SuccessfulMessage;
            Result.IsSuccesful(ResultMsg);
            return View(Result);
        }
    }
}
